package com.bdcom.autotest.interaction.step;

import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.swing.JDialog;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

import com.bdcom.autotest.interaction.bean.DeviceUpdBean;
import com.bdcom.autotest.interaction.socket.DataUtil;
import com.bdcom.autotest.ui.snp.PanelForImportExcel;
import com.bdcom.autotest.ui.snp.PanelForInputDevSN;
import com.bdcom.autotest.ui.snp.PanelForInputWorKNo;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bdcom.autotest.MainFrame;
import com.bdcom.autotest.interaction.bean.DBInfoBean;
import com.bdcom.autotest.interaction.serial.ui.SerialPortFrame;
import com.bdcom.autotest.interaction.serial.utils.ByteUtils;
import com.bdcom.autotest.interaction.socket.DevSocket;
import com.bdcom.autotest.ui.BottomPanel;
import com.bdcom.autotest.ui.CenterPanel;
import com.bdcom.autotest.ui.LeftPanel;
import com.bdcom.autotest.ui.TopPanel;
import com.bdcom.autotest.util.CUtil;
import com.bdcom.autotest.util.Prop;

public class StepThread extends Thread{
	
	private static Logger log = LoggerFactory.getLogger(StepThread.class);
	
	private MainFrame mf;
	
	private TopPanel topp;
	private LeftPanel leftp;
	private CenterPanel centerp;
	private BottomPanel botp;
	private SerialPortFrame serialPort;
	private String nxattPath = System.getProperty("user.dir")+"/conf/NXATT.exe";//测试仪exe地址


	private List<Integer> errorList = new ArrayList();
	private Map<String,String> slotToCardType;
	private Map<String,String> slotToMSUType;
	List<DBInfoBean> cardDBInfo;//nc数据
	String[] idNum;//博达序列号
	private Map<String,DBInfoBean> snToCardDBInfo;//sn对应的nc数据

	int maxRepeatCount = 2;//最大重试次数
	List<String> passCardSn;
	

	private DevSocket devSocket;
	private long startTime;
	
	private boolean endFlag = false;


	private boolean isRestartFlag = false;
	private int mainSlot = 5;


    private String baud = "";

	private Map<String, DeviceUpdBean> macToUpdBean;//sn对应的nc数据
	private List<DeviceUpdBean> enterMonitorResult;//进入monitor结果

	private List<DeviceUpdBean> upgradeResult = new ArrayList<>();//设备升级结果
    private boolean isNewWorkOrder=true;//是否是新一轮的工单


	private String workOrderNum= "";//工单号
	public StepThread(  MainFrame mf  ) {
		super("StepThread-" + System.currentTimeMillis() ) ;
		this.mf = mf;
		topp = mf.getTopp();
		leftp = mf.getLeftp();
		centerp = mf.getCenterp();
		botp = mf.getBottomp();
		serialPort = mf.getSerialPort();
	}
	
	
	public static final String key_pwr_cnt = "pwrcnt";
	public static final String key_fan_cnt = "fancnt";
	public static final String key_slot_cnt = "slotcnt";
	public static final String key_card_cnt = "cardcnt";
	private Map<String, String> shareVars = new HashMap<String, String>();
	
	public void setShareVar(String key , String value ) {
		shareVars.put(key, value);
	}
	public String getShareVar(String key) {
		String str = shareVars.get(key);
		return str;
	}


	private StepBean currentStep = null;

	@Override
	public void run() {
		
		startTestOper();
		
		List<StepBean> toRuns = centerp.getToRuns();
		boolean flag = false;
		int size = toRuns.size();
		for(  int i=0; i< size  ;   ) {
			try {
				if(endFlag){
					break;
				}
				StepBean bean = toRuns.get(i);
				currentStep = bean;
				boolean repeat = bean.getRepeat();
				try {
					flag = runBean(bean);
				} catch (Exception e) {
					log.error( "" ,e );
					flag = false;
				}
				if(   flag ) {
					
				}else if( repeat  ) {
					resetStatus( bean  );
				}else {
					break;
				}
				
				if( flag  ) {
					bean.hidePic();
					if(  i <size-1 ) {
						StepBean next = toRuns.get(i+1);
						next.showPic();
					}
					mf.scrollFlow( bean )  ;
					i++;
				}
				
			} catch (Exception e) {
				log.error( "" ,e );
			}
		}
		currentStep = null;
		endFlag = true;
//		if(serialPort.mSerialport!=null){
////			endSerialTest();
////		}
		endTest(flag);
	}
	
	private void endTest(boolean flag) {
		if(  flag ) {
			addLog(  "测试完成！");
		}else {
			addLog(   "测试不通过!!!");
		}
//		if(devSocket!=null)
//			devSocket.shutdown();
//		mf.setCurretThread(null );
//		mf.endTest(flag);
		if(endFlag){
//			topp.clickCheckBox();
			centerp.resetTimes();
			if(isRestartFlag){//点击重新開始强行结束
				leftp.endTestBtn();
			}else{//正常结束
				leftp.enableStartBtn();
			}

		}
	}
	

	public void startTestOper() {
		mf.setCurretThread(this);
		shareVars.clear();
		System.out.println(  "已经开始测试了" );
	}

	private void resetStatus(StepBean bean) {
		String btn = bean.getBtn();
		if(  (!StringUtils.isEmpty(btn) || bean.getRepeat())&&!endFlag) {
			bean.enableBtn();
		}
	}

	private boolean runBean(StepBean bean) throws Exception {
		
		boolean ret = false;
		
		String btn = bean.getBtn();
		if(  !StringUtils.isEmpty(btn) || (bean.getRepeat()&&bean.getRunTimes()>0) ) {
			waitForClick(bean);
		}
		
		String handleclass = bean.getHandleclass();
		bean.startRun();
		
		if( StringUtils.isEmpty(handleclass) ||"null".equals(handleclass.toLowerCase() ) ) {
			ret = true;
		}else {
			Class<?> forName = Class.forName(handleclass);
			IStepHandler newInstance = (IStepHandler) forName.newInstance();
			ret = newInstance.runStep( this );
		}
		
		if(!endFlag){
			bean.notifyRes(ret);
		}
		bean.addRunTime();
		
		return ret;
		
	}
	
	private Integer sync1 = new Integer(1);
	public void waitForClick(StepBean bean) {
		bean.enableBtn();
		synchronized (sync1) {
			try {
				sync1.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}	
		}
	}
	
	public void goDoRun() {
		synchronized (sync1) {
			sync1.notifyAll();
		}
	}

	private boolean dialogRet = false;
	public boolean showSureWindow(String content, String sureBtn) {
		dialogRet = false;
		new Thread() {
			@Override
			public void run() {
				int result = JOptionPane.showConfirmDialog( mf , (content) ,"确认信息" , JOptionPane.YES_NO_OPTION);
				if( JOptionPane.YES_OPTION == result ){
					dialogRet = true;
				}
				goDoRun();
			}
		}.start();
		
		synchronized (sync1) {
			try {
				sync1.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}	
		}
//		
//		System.out.println("  对话框。。。 ");
		return dialogRet;
	}
	
	public boolean showInfoWindow(String content) {
//		dialogRet = false;
		new Thread() {
			@Override
			public void run() {
				JOptionPane.showMessageDialog( mf ,content,"确认信息",JOptionPane.INFORMATION_MESSAGE );
//				if( JOptionPane.YES_OPTION == result ){
//					dialogRet = true;
//				}
				goDoRun();
			}
		}.start();
		
		synchronized (sync1) {
			try {
				sync1.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}	
		}
//		
//		System.out.println("  对话框。。。 ");
		return dialogRet;
	}
	
	public void setChassisLabel(String chassis){
		topp.setChassisLabel(chassis);
	}
	
//	public boolean showCardWindow(StepThread mainrun) {
//		
//		dialogRet = false;
//		new Thread() {
//			@Override
//			public void run() {
//				JDialog frame = new JDialog();//构造一个新的JFrame，作为新窗口。
//				frame.addWindowListener(new WindowAdapter() {
//					public void windowClosing(WindowEvent e) {
//						int result = JOptionPane.showConfirmDialog(frame , ("确定要关闭 ?") ,"",JOptionPane.YES_NO_OPTION);
//						if( JOptionPane.YES_OPTION == result ){
//							frame.dispose();
//							addLog(   "测试不通过!!!");
//						}
//					}
//				});
//				frame.setTitle("线卡端口状态检查");
//				frame.setLocation(600,200);
////					窗体大小
//				frame.setSize(500,500);
////					显示窗体
//				SnPanelForCardRxTxTest snPanelForCard = new SnPanelForCardRxTxTest(mainrun);
//				JPanel pp = (JPanel) snPanelForCard;
//				frame.add(pp);
//				frame.setAlwaysOnTop(true);
//				frame.setVisible(true);
//				dialogRet = snPanelForCard.getTotalResult();
//				frame.dispose();
//				goDoRun();
////				frame.setModalityType(ModalityType.APPLICATION_MODAL);
//			}
//		}.start();
//		
//		synchronized (sync1) {
//			try {
//				sync1.wait();
//			} catch (InterruptedException e) {
//				e.printStackTrace();
//			}	
//		}
//		
////		System.out.println("  对话框。。。 ");
//		return dialogRet;
//	}
	
//	public boolean showCardFrontPortWindow(StepThread mainrun) {
//		
//		dialogRet = false;
//		new Thread() {
//			@Override
//			public void run() {
//				JDialog frame = new JDialog();//构造一个新的JFrame，作为新窗口。
//				frame.addWindowListener(new WindowAdapter() {
//					public void windowClosing(WindowEvent e) {
//						int result = JOptionPane.showConfirmDialog(frame , ("确定要关闭 ?") ,"",JOptionPane.YES_NO_OPTION);
//						if( JOptionPane.YES_OPTION == result ){
//							frame.dispose();
//							addLog(   "测试不通过!!!");
//						}
//					}
//				});
//				frame.setTitle("前端口性能测试");
//				frame.setLocation(600,200);
////				窗体大小
//				frame.setSize(500,500);
////				显示窗体
//				SnPanelForCradFrontPortTest snPanelForCard = new SnPanelForCradFrontPortTest(mainrun);
//				JPanel pp = (JPanel) snPanelForCard;
//				frame.add(pp);
//				frame.setAlwaysOnTop(true);
//				frame.setVisible(true);
//				dialogRet = snPanelForCard.getTotalResult();
//				frame.dispose();
//				goDoRun();
////				frame.setModalityType(ModalityType.APPLICATION_MODAL);
//			}
//		}.start();
//		
//		synchronized (sync1) {
//			try {
//				sync1.wait();
//			} catch (InterruptedException e) {
//				e.printStackTrace();
//			}	
//		}
//		
////		System.out.println("  对话框。。。 ");
//		return dialogRet;
//	}

//	public boolean showInputWorkNoWindow(StepThread mainrun) {
//
//		dialogRet = false;
//		new Thread() {
//			@Override
//			public void run() {
//				JDialog frame = new JDialog();//构造一个新的JFrame，作为新窗口。
//				frame.addWindowListener(new WindowAdapter() {
//					public void windowClosing(WindowEvent e) {
//						dialogRet = false;
//						goDoRun();
//						addLog("测试不通过!!!");
//						frame.dispose();
//					}
//
//				});
//				frame.setTitle("输入工单号");
//				frame.setLocationRelativeTo(null);
////				窗体大小
//				frame.setSize(500, 120);
////				显示窗体
//				PanelForInputWorKNo panelForInputWorKNo = new PanelForInputWorKNo(mainrun);
//				JPanel pp = (JPanel) panelForInputWorKNo;
//				frame.add(pp);
//				frame.setVisible(true);
//				dialogRet = panelForInputWorKNo.getTotalResult();
//				frame.dispose();
//				goDoRun();
////				frame.setModalityType(ModalityType.APPLICATION_MODAL);
//			}
//		}.start();
//
//		synchronized (sync1) {
//			try {
//				sync1.wait();
//			} catch (InterruptedException e) {
//				e.printStackTrace();
//			}
//		}
//
////		System.out.println("  对话框。。。 ");
//		return dialogRet;
//	}

	public boolean showInputDevSNWindow(StepThread mainrun,int idx) {

		dialogRet = false;
		new Thread() {
			@Override
			public void run() {
				JDialog frame = new JDialog();//构造一个新的JFrame，作为新窗口。
				frame.addWindowListener(new WindowAdapter() {
					public void windowClosing(WindowEvent e) {
						dialogRet = false;
						goDoRun();
//						addLog("测试不通过!!!");
						frame.dispose();
					}

				});
				frame.setTitle("扫描设备"+idx+" Mac");
				frame.setLocationRelativeTo(null);
//				窗体大小
				frame.setSize(500, 120);
//				显示窗体
				PanelForInputDevSN panelForInputDevSN = new PanelForInputDevSN(mainrun,idx);
				JPanel pp = (JPanel) panelForInputDevSN;
				frame.setAlwaysOnTop(true);
				frame.add(pp);
				frame.setVisible(true);
				dialogRet = panelForInputDevSN.getTotalResult();
				frame.dispose();
				goDoRun();
//				frame.setModalityType(ModalityType.APPLICATION_MODAL);
			}
		}.start();

		synchronized (sync1) {
			try {
				sync1.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}

//		System.out.println("  对话框。。。 ");
		return dialogRet;
	}

	public boolean showImportExcelWindow(StepThread mainrun) {

		dialogRet = false;
		new Thread() {
			@Override
			public void run() {
				JDialog frame = new JDialog();//构造一个新的JFrame，作为新窗口。
				frame.addWindowListener(new WindowAdapter() {
					public void windowClosing(WindowEvent e) {
						dialogRet = false;
						goDoRun();
//						addLog("测试不通过!!!");
						frame.dispose();
					}

				});
				frame.setTitle("选择要导入的Excel文件");
				frame.setLocationRelativeTo(null);
//				窗体大小
				frame.setSize(300, 100);
//				显示窗体
				PanelForImportExcel panelForImportExcel = new PanelForImportExcel(mainrun);
				JPanel pp = (JPanel) panelForImportExcel;
				frame.add(pp);
				frame.setVisible(true);
				dialogRet = panelForImportExcel.getTotalResult();
				frame.dispose();
				goDoRun();
//				frame.setModalityType(ModalityType.APPLICATION_MODAL);
			}
		}.start();

		synchronized (sync1) {
			try {
				sync1.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}

//		System.out.println("  对话框。。。 ");
		return dialogRet;
	}
//public boolean showMSSwitchWindow(StepThread mainrun) {
//		
//		dialogRet = false;
//		new Thread() {
//			@Override
//			public void run() {
//				JDialog frame = new JDialog();//构造一个新的JFrame，作为新窗口。
//				frame.addWindowListener(new WindowAdapter() {
//					public void windowClosing(WindowEvent e) {
//						int result = JOptionPane.showConfirmDialog(frame , ("确定要关闭 ?") ,"",JOptionPane.YES_NO_OPTION);
//						if( JOptionPane.YES_OPTION == result ){
//							frame.dispose();
//							addLog(   "测试不通过!!!");
//						}
//					}
//				});
//				frame.setTitle("主备切换测试");
//				frame.setLocation(700,400);
////				窗体大小
//				frame.setSize(220,150);
////				显示窗体
//				MSSwitchTest snPanelForCard = new MSSwitchTest(mainrun);
//				JPanel pp = (JPanel) snPanelForCard;
//				frame.add(pp);
//				frame.setAlwaysOnTop(true);
//				frame.setVisible(true);
//				dialogRet = snPanelForCard.getTotalResult();
//				frame.dispose();
//				goDoRun();
////				frame.setModalityType(ModalityType.APPLICATION_MODAL);
//			}
//		}.start();
//		
//		synchronized (sync1) {
//			try {
//				sync1.wait();
//			} catch (InterruptedException e) {
//				e.printStackTrace();
//			}	
//		}
//		
////		System.out.println("  对话框。。。 ");
//		return dialogRet;
//	}

	public void addErrorLog( String log ) {
		mf.appendLog("XX " + log , true);
	}
	
	public void addLog( String log ) {
		mf.appendLog(log , false);
	}
	
	public void addLog2( String log ) {
		mf.appendLog2(log , false);
	}
	
	public MainFrame getMf() {
		return mf;
	}
	public void setMf(MainFrame mf) {
		this.mf = mf;
	}
	
	public String[] getSNs() {
		
		LeftPanel leftp2 = mf.getLeftp();
		String[] getsns = leftp2.getsns();
		return getsns;
	}
	
	public void setSNs( String[ ]   sns ) {
		mf.getLeftp().setsns(sns);
	}
	public DevSocket getDevSokcet() {
		return devSocket;
	}
	public void setDevSokcet(DevSocket devSocket) {
		this.devSocket = devSocket;
	}
	public StepBean getCurrentStep() {
		return currentStep;
	}
	public void setCurrentStep(StepBean currentStep) {
		this.currentStep = currentStep;
	}
	
	public List<Integer> getErrorList() {
		return errorList;
	}
	public void setErrorList(List<Integer> errorList) {
		this.errorList = errorList;
	}
	
//	public void addServerLogBySNs(  TestLog log,String[] devSn ) {
//		for(String sn: devSn){
//			log.setDevSn(sn);
//			log.setType(Prop.testType);
//			addServerLog(log);
//		}
//	}
//
//	public void addServerLog(  TestLog log ) {
//
//		JSONObject json = log.toJson();
//
//		String reqUrl = "/tlog/addlog";
//		JSONObject args = new JSONObject();
//		args.put("log", json);
//
//		JSONObject httpPost = CUtil.httpPost(args, reqUrl);
//
//
//
//	}
	public boolean isPassBaseTest(String sn){
		boolean isPass = false;
		JSONArray logList  = queryBaseLogsBySn(sn);
		if(logList.size() == 0)//没有记录
			return isPass;
		for(Object obj:logList){
			JSONObject logObj = (JSONObject)obj;
			String result = logObj.getString("res");
			if("通过".equals(result)){
				isPass = true;
				continue;
			}
		}
		return isPass;
	}
	
	public JSONArray queryBaseLogsBySn(  String sn ) {
		String reqUrl = "/tlog/queryBaseLogsBySn";
		JSONObject args = new JSONObject();
		args.put("SN", sn);
		JSONObject httpPost = CUtil.httpPost(args, reqUrl);
		JSONArray logList = httpPost.getJSONArray("logList");
		return logList;
	}

	public void setFail(List<String> sns){
		leftp.setFail(sns);
	}

	public void setResult(List<String> sns){
		leftp.setResult(sns);
	}
	public String getnxattPath() {
		return nxattPath;
	}
	public void setnxattPath(String nxattPath) {
		this.nxattPath = nxattPath;
	}
	public Map<String, String> getSlotToCardType() {
		return slotToCardType;
	}
	public void setSlotToCardType(Map<String, String> slotToCardType) {
		this.slotToCardType = slotToCardType;
	}
	public Map<String, String> getSlotToMSUType() {
		return slotToMSUType;
	}
	public void setSlotToMSUType(Map<String, String> slotToMSUType) {
		this.slotToMSUType = slotToMSUType;
	}
	public List<DBInfoBean> getCardDBInfo() {
		return cardDBInfo;
	}
	public void setCardDBInfo(List<DBInfoBean> cardDBInfo) {
		this.cardDBInfo = cardDBInfo;
	}
	public long getStartTime() {
		return startTime;
	}
	public void setStartTime(long startTime) {
		this.startTime = startTime;
	}
	public boolean isEndFlag() {
		return endFlag;
	}
	public void setEndFlag(boolean endFlag) {
		this.endFlag = endFlag;
	}
	public int getMainSlot() {
		return mainSlot;
	}
	public void setMainSlot(int mainSlot) {
		this.mainSlot = mainSlot;
	}
	public List<String> getPassCardSn() {
		return passCardSn;
	}
	public void setPassCardSn(List<String> passCardSn) {
		this.passCardSn = passCardSn;
	}
	public String[] getIdNum() {
		return idNum;
	}
	public void setIdNum(String[] idNum) {
		this.idNum = idNum;
	}
	public Map<String, DBInfoBean> getSnToCardDBInfo() {
		return snToCardDBInfo;
	}
	public void setSnToCardDBInfo(Map<String, DBInfoBean> snToCardDBInfo) {
		this.snToCardDBInfo = snToCardDBInfo;
	}
	public void sendDataByBytes(byte[] order) {
		this.addLog("发送"+ByteUtils.byteArrayToHexString(order));
		this.serialPort.sendDataByBytes(order);;
	}
	
	public byte[] readFromPort() {
		byte[] order = this.serialPort.readFromPort();
		if(order.length>0){
			this.addLog("接收"+ByteUtils.byteArrayToHexString(order));
		}
		return order;
	}
	
	public boolean startSerialTest() {
		return this.serialPort.startTest();
	}
	
	public void endSerialTest() {
		this.serialPort.endTest();
	}

	public Map<String, DeviceUpdBean> getMacToUpdBean() {
		return macToUpdBean;
	}

	public void setMacToUpdBean(Map<String, DeviceUpdBean> oemsnToUpdBean) {
		this.macToUpdBean = oemsnToUpdBean;
	}

	public List<DeviceUpdBean> getEnterMonitorResult() {
		return enterMonitorResult;
	}

	public void setEnterMonitorResult(List<DeviceUpdBean> enterMonitorResult) {
		this.enterMonitorResult = enterMonitorResult;
	}

	public String getBaud() {
		return baud;
	}

	public void setBaud(String baud) {
		this.baud = baud;
	}

	public List<DeviceUpdBean> getDeviceUpdBeanList(){
		String sns[] = DataUtil.deleteArrayNull(mf.getLeftp().getsns());
		List<DeviceUpdBean> deviceUpdBeanList = new ArrayList<>();
		for(String sn:sns){
			deviceUpdBeanList.add(macToUpdBean.get(sn));
		}
		return deviceUpdBeanList;
	}

    public boolean isNewWorkOrder() {
        return isNewWorkOrder;
    }

    public void setNewWorkOrder(boolean newWorkOrder) {
        isNewWorkOrder = newWorkOrder;
    }

	public boolean isRestartFlag() {
		return isRestartFlag;
	}

	public void setRestartFlag(boolean restartFlag) {
		isRestartFlag = restartFlag;
	}

	public List<DeviceUpdBean> getUpgradeResult() {
		return upgradeResult;
	}

	public void setUpgradeResult(List<DeviceUpdBean> upgradeResult) {
		this.upgradeResult = upgradeResult;
	}

	public int getMaxRepeatCount() {
		return maxRepeatCount;
	}

	public void setMaxRepeatCount(int maxRepeatCount) {
		this.maxRepeatCount = maxRepeatCount;
	}

	public String getWorkOrderNum() {
		return workOrderNum;
	}

	public void setWorkOrderNum(String workOrderNum) {
		this.workOrderNum = workOrderNum;
	}
}
